package org.jeese.handler;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.jeese.bean.JsonResult;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Joiner;

@ControllerAdvice
public class GlobalExceptionHandler {
	/**
	 * 参数绑定异常
	 * @param exception
	 * @return
	 */
	@ResponseBody
	@ExceptionHandler({ MethodArgumentNotValidException.class, ConstraintViolationException.class, BindException.class })
	public JsonResult handleValidException(Exception exception) {
		BindingResult bindResult = null;
		List<String> list = new ArrayList<String>();
		if (exception instanceof MethodArgumentNotValidException) {
			bindResult = ((MethodArgumentNotValidException) exception).getBindingResult();
		} else if (exception instanceof ConstraintViolationException) {
			Set<ConstraintViolation<?>> constraintViolations = ((ConstraintViolationException) exception).getConstraintViolations();
			for (ConstraintViolation<?> violation : constraintViolations) {
				list.add(violation.getMessage());
			}
		} else if (exception instanceof BindException) {
			bindResult = ((BindException) exception).getBindingResult();
		}
		if (bindResult != null) {
			for (ObjectError objectError : bindResult.getAllErrors()) {
				list.add(objectError.getDefaultMessage());
			}
		}
		return new JsonResult().error(Joiner.on(",").skipNulls().join(list));
	}
	
	@ExceptionHandler(value = NoHandlerFoundException.class)
    public Object handlerNoHandlerFoundException(HttpServletRequest request, HttpServletResponse response, NoHandlerFoundException e) throws Exception{
		if ("GET".equalsIgnoreCase(request.getMethod())) {
			ModelAndView modelAndView = new ModelAndView();
			modelAndView.setViewName("/404.html");
			modelAndView.addObject("exception", e);
			return modelAndView;
		} else {
			ObjectMapper objectMapper = new ObjectMapper();
			response.setContentType("application/json; charset=utf-8");
			JsonResult jsonResult = new JsonResult();
			jsonResult.error("访问请求地址不存在");
			jsonResult.put("url", request.getRequestURI());
	        PrintWriter writer = response.getWriter();
            writer.println(objectMapper.writeValueAsString(jsonResult));
            writer.flush();
            writer.close();
            return null;
		}
    }
}
